<!--
 * @Author: Wushiqi
 * @Descripttion: promise
 * @Date: 2021-04-28 09:59:20
 * @LastEditor: Wushiqi
 * @LastEditTime: 2021-04-28 15:57:54
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 平常使用Promise
    // const p = new Promise((resolve, reject) => {
    //   console.log('执行');
    //   setTimeout(() => {
    //     // resolve(11)
    //     reject(55)
    //   }, 2000);
    // })
    // p.then(res => {
    //   console.log(res);
    // }).catch(err => {
    //   console.log(err);
    // })

    // 从以上可以看出，Promise是通过构造函数实例化一个对象，
    // 然后通过实例对象上的then方法，来处理一部返回的结果。
    // 同时，promise/A+规范规定：
    // 1.promise是一个拥有then方法的对象或函数；
    // 2.一个Promise的当前状态为以下三种的其中一种：
    //     等待态（pending）、执行态（fulfilled）、拒绝态（rejected）
    
    // 定义三种状态
    const PENDING = 'pengding'
    const FULFILLED = 'fulfilled'
    const REJECTED = 'rejected'
    function MyPromise(excutor) { // Promise添加实例时会立即执行
      const _this = this
      this.state = PENDING // 状态
      this.value = undefined // 成功结果
      this.reason = undefined // 失败结果（原因）
      
      this.onFulfilled = [] // 成功的回调
      this.onRejected = [] // 失败的回调
      function resolve(value) {
        // 由于Promise状态不可变
        // 只有状态为PENDING时才可以更改状态
        if (_this.state === PENDING) {
          _this.state = FULFILLED
          _this.value = value
          // 执行存储的回调函数
          _this.onFulfilled.forEach(fn => fn(value))
        }
      }
      function reject(reason) {
        if (_this.state === PENDING) {
          _this.state = REJECTED
          _this.reason = reason
          // 执行存储的回调函数
          _this.onRejected.forEach(fn => fn(reason))
        }
      }
      try {
        excutor(resolve, reject)
      } catch (error) {
        reject(error)
      }
    }
    // 在Promise原型上添加then方法
    MyPromise.prototype.then = function(onFulfilled, onRejected) {
      // 当Promise的状态改变之后，不管是成功还是失败都会触发then回调函数
      // 因此，then的需要根据状态不同，来调用不同处理终值的函数
      if (this.state === FULFILLED) {
        typeof onFulfilled === 'function' && onFulfilled(this.value)
      }
      if (this.state === REJECTED) {
        typeof onRejected === 'function' && onRejected(this.reason)
      }
      // 如果状态还没改变，将回调函数存储到数组，当resolve或reject异步执行时调用
      if (this.state === PENDING) {
        typeof onFulfilled === 'function' && this.onFulfilled.push(onFulfilled)
        typeof onRejected === 'function' && this.onRejected.push(onRejected)
      }
    }
    const mp = new MyPromise((resolve, reject) => {
      console.log('执行了');
      // resolve('触发了resolve')
      setTimeout(() => {
        reject('触发了reject')
      }, 3000);
    }).then(
      res => console.log(res),
      err => console.log(err)
    )
  </script>
</body>
</html>